package com.ssm.util;


import java.util.List;
import java.util.Map;

import lombok.Data;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;

/** 
 * 封装分页数据 
 */  
@Data
public class Page 
{  
  
  private static final Logger logger = LoggerFactory.getLogger(Page.class);  
  private static Gson mapper = new Gson();  
  
  public static String DEFAULT_PAGESIZE = "10";  
  private int pageNo;          //当前页码  
  private int pageSize;        //每页行数  
  private int topPageSize;     //sqlserver 外层查询数量
  private int notPageSize;     //sqlserver 不包含的数量
  private int totalRecord;      //总记录数  
  private int totalPage;        //总页数  
  private Map<String, String> params;  //查询条件  
  private Map<String, List<String>> paramLists;  //数组查询条件  
  private String searchUrl;      //Url地址  
  private String pageNoDisp;       //可以显示的页号(分隔符"|"，总页数变更时更新)  
  
  public int getTotalRecord() {  
     return totalRecord;  
  }  
  public void setTotalRecord(int totalRecord) {  
    this.totalRecord = totalRecord;  
    refreshPage();       
  }  
  
  public Page() {  
    pageNo = 1;  
    pageSize = Integer.valueOf(DEFAULT_PAGESIZE);  
    totalRecord = 0;  
    totalPage = 0;  
    params = Maps.newHashMap();  
    paramLists = Maps.newHashMap();  
    searchUrl = "";  
    pageNoDisp = "";  
  }  
  
  public Page(int pageNo, int pageSize){
	  this.pageNo = pageNo;
	  this.pageSize = pageSize;
  }
  
  public static Page newBuilder(int pageNo, int pageSize, String url){  
    Page page = new Page();  
    page.setPageNo(pageNo);  
    page.setPageSize(pageSize);  
    page.setSearchUrl(url);  
    return page;  
  }  
    
  /** 
   * 查询条件转JSON 
   */  
  public String getParaJson(){  
    Map<String, Object> map = Maps.newHashMap();  
    for (String key : params.keySet()){  
      if ( params.get(key) != null  ){  
        map.put(key, params.get(key));  
      }  
    }  
    String json="";  
    try {  
      json = mapper.toJson(map); 
    } catch (Exception e) {  
      logger.error("转换JSON失败", params, e);  
    }  
    return json;  
  }  
  
  /** 
   * 数组查询条件转JSON 
   */  
  public String getParaListJson(){  
    Map<String, Object> map = Maps.newHashMap();  
    for (String key : paramLists.keySet()){  
      List<String> lists = paramLists.get(key);  
      if ( lists != null && lists.size()>0 ){  
        map.put(key, lists);  
      }  
    }  
    String json="";  
    try {  
      json = mapper.toJson(map);
    } catch (Exception e) {  
      logger.error("转换JSON失败", params, e);  
    }  
    return json;  
  }  
  
  /** 
   * 总件数变化时，更新总页数并计算显示样式 
   */  
  private void refreshPage(){  
    //总页数计算  
    totalPage = totalRecord%pageSize==0 ? totalRecord/pageSize : (totalRecord/pageSize + 1);  
    //防止超出最末页（浏览途中数据被删除的情况）  
    if ( pageNo > totalPage && totalPage!=0){  
        pageNo = totalPage;  
    }  
    //sqlserver 查询总量
    //最后一页并且余数不为0 则查询数量不是整页大小
    topPageSize = (pageNo == totalPage && totalRecord%pageSize != 0) ? totalRecord % pageSize : pageSize;
    //sqlserver 不包含的数量
    notPageSize = pageNo == 1 ? 0 : pageSize * (pageNo - 1);
    pageNoDisp = computeDisplayStyleAndPage();  
  }  
    
  /** 
   * 计算页号显示样式 
   *  这里实现以下的分页样式("[]"代表当前页号)，可根据项目需求调整 
   *   [1],2,3,4,5,6,7,8..12,13 
   *   1,2..5,6,[7],8,9..12,13 
   *   1,2..6,7,8,9,10,11,12,[13] 
   */  
  private String computeDisplayStyleAndPage(){  
      List<Integer> pageDisplays = Lists.newArrayList();  
      if ( totalPage <= 5 ){  
          for (int i=1; i<=totalPage; i++){  
              pageDisplays.add(i);  
          }  
      }else if ( pageNo <= 3 ){  
          for (int i=1; i<=3; i++){  
              pageDisplays.add(i);  
          }  
          pageDisplays.add(0);// 0 表示 省略部分(下同)  
          pageDisplays.add(totalPage-1);         
          pageDisplays.add(totalPage);  
      }else if ( pageNo> totalPage-3 ){  
          pageDisplays.add(1);  
          pageDisplays.add(2);  
          pageDisplays.add(0);  
          for (int i=totalPage-2; i<=totalPage; i++){  
              pageDisplays.add(i);  
          }         
      }else{  
          pageDisplays.add(1);  
          pageDisplays.add(0);  
          for (int i=pageNo-1; i<=pageNo+1; i++){  
              pageDisplays.add(i);  
          }  
          pageDisplays.add(0);  
          pageDisplays.add(totalPage);  
      }  
      return Joiner.on("|").join(pageDisplays.toArray());  
  }  
}  